library(dplyr)
library(sf)
library(ggplot2)
library(remotes)
remotes::install_github('ropensci/osmdata')
library(osmdata)
library(osmextract)
Open Street Map (OSM) is a collaborative project which aims at mapping the world and sharing geospatial data in an open way. Anyone can contribute, by mapping geographical objects their encounter, by adding topical information on existing map objects (their name, function, capacity, etc.), or by mapping buildings and roads from satellite imagery (cf. HOT: Humanitarian OpenStreetMap Team).
This information is then validated by other users and eventually added to the common “map” or information system. This ensures that the information is accessible, open, verified, accurate and up-to-date.
The result looks like this: The geospatial data underlying this
interface is made of geometrical objects (i.e. points, lines, polygons)
and their associated tags (#building #height, #road #secondary #90kph,
etc.).
The first thing to do is to define the area within which you want to
retrieve data, aka the bounding box. This can be defined easily
using a place name and the function getbb() from the
package osmdata.
“This function uses the free Nominatim API provided by OpenStreetMap to find the bounding box (bb) associated with place names.”
assign("has_internet_via_proxy", TRUE, environment(curl::has_internet))
bb <- getbb('Delft', format_out = 'sf_polygon')
bb
Simple feature collection with 3 features and 0 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 4.320218 ymin: 9.474415 xmax: 79.73152 ymax: 52.0326
Geodetic CRS: WGS 84
geometry
1 POLYGON ((4.320218 52.00807...
2 POLYGON ((4.320218 52.00807...
3 POLYGON ((79.65064 9.541313...
Because there are different responses from the API query, corresponding to different objects at the same location, or different objects are different locations.
A feature in
the OSM language is a category or tag of a geospatial object. Features
are described by general keys (e.g. “building”, “boundary”, “landuse”,
“highway”), themselves decomposed into sub-categories (values) such as
“farm”, “hotel” or “house” for buildings, “motorway”,
“secondary” and “residential” for highway. This determines
how they are represented on the map.
x <- opq(bbox = bb) %>%
add_osm_feature(key = 'building') %>%
osmdata_sf ()
What is this x object made of? It is a table of all the buildings contained in the bounding box, which gives us their OSM id, their geometry and a range of attributes, such as their name, building material, building date, etc. The completion level of this table depends on user contributions and open resources (here for instance: BAG, different in other countries).
head(x$osm_polygons)
Simple feature collection with 6 features and 145 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 4.371179 ymin: 51.99641 xmax: 4.39319 ymax: 52.006
Geodetic CRS: WGS 84
osm_id name access addr.city addr.country addr.housename
7536962 7536962 Sporthal Emerald <NA> Delfgauw NL <NA>
32017871 32017871 <NA> <NA> <NA> <NA> <NA>
32017872 32017872 <NA> <NA> <NA> <NA> <NA>
32017873 32017873 <NA> <NA> <NA> <NA> <NA>
32045333 32045333 Cambridge <NA> <NA> <NA> <NA>
32045334 32045334 Oxford <NA> <NA> <NA> <NA>
addr.housenumber addr.postcode addr.street alt_name amenity
7536962 1 2645HH Florijnstraat <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA>
antenna.type area barrier bicycle_parking bridge bridge.support
7536962 <NA> <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA> <NA>
building building.colour building.flats building.levels
7536962 yes <NA> <NA> <NA>
32017871 apartments <NA> <NA> 6
32017872 apartments <NA> <NA> 6
32017873 apartments <NA> <NA> 6
32045333 yes <NA> <NA> 5
32045334 apartments <NA> <NA> 5
building.levels.aboveground building.levels.underground
7536962 <NA> <NA>
32017871 <NA> <NA>
32017872 <NA> <NA>
32017873 <NA> <NA>
32045333 <NA> <NA>
32045334 <NA> <NA>
building.material building.min_level building.part building.use
7536962 <NA> <NA> <NA> <NA>
32017871 brick <NA> <NA> <NA>
32017872 brick <NA> <NA> <NA>
32017873 brick <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA>
capacity check_date check_date.existence club colour construction
7536962 <NA> <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA> <NA>
contact.phone content covered craft cuisine denomination description
7536962 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
disused.amenity disused.building disused.building.colour disused.power
7536962 <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA>
disused.roof.colour drinking_water email emergency exit fee fixme
7536962 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
generator.method generator.output.electricity generator.source
7536962 <NA> <NA> <NA>
32017871 <NA> <NA> <NA>
32017872 <NA> <NA> <NA>
32017873 <NA> <NA> <NA>
32045333 <NA> <NA> <NA>
32045334 <NA> <NA> <NA>
generator.type healthcare height heritage heritage.operator highway
7536962 <NA> <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> 15 <NA> <NA> <NA>
32045334 <NA> <NA> 15 <NA> <NA> <NA>
historic image layer leisure level level.usage levels lit
7536962 <NA> <NA> <NA> sports_centre <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
loc_name location man_made material min.height min_height museum
7536962 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
museum_type name.en name.nl name.ru name.zh network note old_name
7536962 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
old_name.wikidata opening_hours opening_hours.signed operator
7536962 <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA>
operator.type operator.wikidata operator.wikipedia outdoor_seating
7536962 <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA>
parking payment.cash payment.maestro phone power private
7536962 <NA> <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA> <NA>
pumping_station ref ref.bag ref.bag.old ref.heritage ref.rce
7536962 <NA> <NA> 1926100000497049 <NA> <NA> <NA>
32017871 <NA> <NA> 503100000024959 <NA> <NA> <NA>
32017872 <NA> <NA> 503100000024957 <NA> <NA> <NA>
32017873 <NA> <NA> 503100000024958 <NA> <NA> <NA>
32045333 <NA> <NA> 503100000030621 <NA> <NA> <NA>
32045334 <NA> <NA> 503100000030621 <NA> <NA> <NA>
ref.tudelft religion removed.building roof.colour roof.direction
7536962 <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA>
roof.edge roof.height roof.levels roof.material roof.orientation
7536962 <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA>
roof.ridge roof.shape service_times shop short_name smoking
7536962 <NA> <NA> <NA> <NA> <NA> <NA>
32017871 <NA> flat <NA> <NA> <NA> <NA>
32017872 <NA> flat <NA> <NA> <NA> <NA>
32017873 <NA> flat <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA> <NA>
social_facility.for source source.date source.name
7536962 <NA> BAG 2013-09-01;2013-11-26 <NA>
32017871 <NA> BAG 2013-11-26 <NA>
32017872 <NA> BAG 2013-11-26 <NA>
32017873 <NA> BAG 2013-11-26 <NA>
32045333 <NA> BAG 2013-11-26 <NA>
32045334 <NA> BAG 2013-11-26 <NA>
source.old_name sport start_date street_cabinet substation surface
7536962 <NA> <NA> 2001 <NA> <NA> <NA>
32017871 <NA> <NA> 2008 <NA> <NA> <NA>
32017872 <NA> <NA> 2008 <NA> <NA> <NA>
32017873 <NA> <NA> 2008 <NA> <NA> <NA>
32045333 <NA> <NA> 2007 <NA> <NA> <NA>
32045334 <NA> <NA> 2007 <NA> <NA> <NA>
survey.date toilets tourism tower.type type url voltage
7536962 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
watermill.disused website wheelchair wheelchair.description wikidata
7536962 <NA> <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA> <NA>
wikidata_1 wikipedia windmill.type windmill.vanes
7536962 <NA> <NA> <NA> <NA>
32017871 <NA> <NA> <NA> <NA>
32017872 <NA> <NA> <NA> <NA>
32017873 <NA> <NA> <NA> <NA>
32045333 <NA> <NA> <NA> <NA>
32045334 <NA> <NA> <NA> <NA>
geometry
7536962 POLYGON ((4.392537 52.00466...
32017871 POLYGON ((4.37131 51.99711,...
32017872 POLYGON ((4.371664 51.9966,...
32017873 POLYGON ((4.371552 51.99676...
32045333 POLYGON ((4.372431 52.00586...
32045334 POLYGON ((4.372391 52.00555...
For instance: the building age focusing on post-1900 buildings.
First, we are going to select the polygons and reproject them with the Amersfoort/RD New projection, suited for maps centred on the Netherlands.
buildings <- x$osm_polygons %>% st_transform(.,crs=28992)
Then we create a variable which a threshold at 1900. Every date prior to 1900 will be recoded 1900, so that buildings older than 1900 will be represented with the same shade.
Then we use the ggplot function to visualise the
buildings by age. The specific function to represent information as a
map is geom_sf(). The rest works like other graphs and
visualisation, with aes() for the aesthetics.
buildings$build_date <- as.numeric(ifelse(buildings$start_date <1900, 1900,buildings$start_date))
ggplot(data = buildings) +
geom_sf(aes(fill = build_date, colour=build_date)) +
scale_fill_viridis_c(option = "viridis")+
scale_colour_viridis_c(option = "viridis")
So this reveals the historical centre of Delft and the various extensions, the first ring in the 1920s, towards the South-West of the city (1970s-1990s), East of the city (2000s) and North-West (2010s). This centre-periphery and sectoral urban development is quite common. Now for a less typical example, can you reproduce this map for the city of Rotterdam. But instead of pre-XXth century building, we want to look at pre-war buildings. It will take some time to extract all buildings, so we will check the result after the coffee break.
We have seen how OpenStreetMap (OSM) geodata works and how to import, select, and visualise OSM vector data.
In short:
osmextract packageggplot package to map OSM data